
`include "common_header.verilog"

//  *************************************************************************
//  File : p8264_pcs_mld_tx.v
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized reproduction or use is expressly prohibited.
//  Copyright (c) 2009 MorethanIP
//  Muenchner Strasse 199, 85757 Karlsfeld, Germany
//  info@morethanip.com
//  http://www.morethanip.com
//  *************************************************************************
//  Designed by : Denis Poverennyy
//  info@morethanip.com
//  *************************************************************************
//  Description : 40G PCS 64 bit: Transmit Top Level Structure
//      for PCS (Encoder + Scrambler), MLD and optional EEE SM.
//  Version     : $Id: p8264_pcs_mld_tx.v,v 1.7 2017/01/12 11:49:48 wt Exp $
//  *************************************************************************


module p8264_pcs_mld_tx (

        reset_txclk,    
        cgmii_txclk,    
        sw_reset,                
        cgmii_txc,      
        cgmii_txd,      
        cgmii_txclk_ena,
        cgmii_tx_tsu,
        tx_mld_d0,        
        tx_mld_d1,        
        tx_mld_d2,        
        tx_mld_d3,
        marker_start,                         
        mld_rd,
        scr_bypass,
        vl_intvl,                
        vl_0_enc,       
        vl_1_enc,       
        vl_2_enc,       
        vl_3_enc,       
`ifdef MTIPPCS82_EEE_ENA 
        lpi_tick,                 
        lpi_fw,  
        scr_bypass_enable,                         
        tx_lpi_mode,      
        tx_lpi_state,     
        tx_lpi_indication,
 `endif
        tx_en_gen_pat,
        disable_mld,
        mode25,
        en_gen_pat49,
        sel_pat,
        seed_1,
        seed_2,
        marker_ins_cnt
            
);
                                         
                 
input           reset_txclk;            // async active high reset
input           cgmii_txclk;            // system ref clock
input           sw_reset;               // Software Reset
                 
input   [7:0]   cgmii_txc;              // XL/CGMII transmit control
input   [63:0]  cgmii_txd;              // XL/CGMII transmit data
output          cgmii_txclk_ena;        // XL/CGMII transmit clock enable
output  [1:0]   cgmii_tx_tsu;          // bit 0: Cycle start, bit 1: AM start

output  [65:0]  tx_mld_d0;              // output mld datastream
output  [65:0]  tx_mld_d1;              // output mld datastream
output  [65:0]  tx_mld_d2;              // output mld datastream
output  [65:0]  tx_mld_d3;              // output mld datastream
output          marker_start;           // marker start indication                 
                 
input           mld_rd;                 // read from the mld (data must be ready with zero latency)
input           scr_bypass;             // bypass scrambling and descrambling within PCS
input   [15:0]  vl_intvl;               // AM Period control (if 1,then test mode)                 
input   [23:0]  vl_0_enc;               // Marker pattern for PCS Virtual Lane 0
input   [23:0]  vl_1_enc;               // Marker pattern for PCS Virtual Lane 1
input   [23:0]  vl_2_enc;               // Marker pattern for PCS Virtual Lane 2
input   [23:0]  vl_3_enc;               // Marker pattern for PCS Virtual Lane 3

`ifdef MTIPPCS82_EEE_ENA 

input  		lpi_tick;		// A timer tick, which asserts for one reference clock (ref_clk) cycle in average every 100ns.
input           lpi_fw;                 // FastWake(1) or DeepSleep(0) support.
input           scr_bypass_enable;      // Indicate to the transmit LPI state diagram that the scrambler bypass option is required. FEC74 is enabled.
output  [1:0]   tx_lpi_mode;            // A variable reflecting state of the LPI transmit function as described by the LPI transmit state diagram (Figure 82-16).
output  [2:0]   tx_lpi_state;           // A variable reflecting state of the LPI SM as described by the LPI transmit state  diagram (Figure 82-16).
output          tx_lpi_indication;      // status 1[9]:  Tx LPI indication A Boolean variable indicating the transmit LPI function is not TX_ACTIVE. 

`endif

input           tx_en_gen_pat;          //  enable test pattern generator
input           disable_mld;            //  disable MLD (10G/25G mode setting)
input           mode25;                 //  configure MLD use for 25G omitting BIP insertion
input           en_gen_pat49;           //  Enable 10G Test pattern generator (49.2.8) 
input           sel_pat;                //  Select pattern : 1 => 00 / 0 => Local Fault 
input   [57:0]  seed_1;                 //  Seed 1
input   [57:0]  seed_2;                 //  Seed 2
output  [15:0]  marker_ins_cnt;         // marker insertion counter

//--------------------------------------
// Output Signals
//--------------------------------------

wire            cgmii_txclk_ena;
wire    [65:0]  tx_mld_d0;                 
wire    [65:0]  tx_mld_d1;                 
wire    [65:0]  tx_mld_d2;                 
wire    [65:0]  tx_mld_d3;
wire            marker_start;

`ifdef MTIPPCS82_EEE_ENA 

wire    [1:0]   tx_lpi_mode;
wire    [2:0]   tx_lpi_state;
wire            tx_lpi_indication;

`endif

//--------------------------------------
// Internal Signals
//--------------------------------------
                 
wire    [63:0]  enc64_dout;             //  data encoded 64B/66B format                 (encoder output)   
wire    [1:0]   enc64_tout;             //  data block type (10: data / 01: control)    (encoder output)  
wire    [63:0]  scr64_dout;             //  data scrambled 64B/66B format               (scrambler output)   
wire    [1:0]   scr64_tout;             //  data block type (10: data / 01: control)    (scrambler output)   

wire            cgmii_txclk_ena_int;

`ifdef MTIPPCS82_EEE_ENA 

wire            scrambler_bypass;       // Bypass the Tx PCS scrambler in order to assist rapid synchronization following low power idle.
wire            scrambler_bypass_c;     // combined with global scr_bypass
wire            t_type_li;              //  LI Block type received
wire            ram_start;              // RAM mode
wire            down_count_enable;      // Boolean variable controlling decrement of the counter down_count. This variable is set by the LPI transmit state diagram.
wire    [7:0]   down_count;             // A counter that is used in rapid alignment markers and is decremented each time a RAM is sent.   
wire            down_count_load;        // write for down_count value
wire            no_ram;                 // the LPI SM either in the TX_ACTIVE or TX_FW 


// Control EEE transmit
// --------------------

p824964_eee_ctl_tx U_EEECTLTX (

        .reset_txclk(reset_txclk),    
        .cgmii_txclk(cgmii_txclk),    
        .sw_reset(sw_reset),                
        .disable_mld(disable_mld),        
        .t_type_li(t_type_li),
        .scrambler_bypass(scrambler_bypass),
        
        // interface to MLD
        
        .ram_start(ram_start),
        .down_count_enable(down_count_enable),
        .down_count(down_count),
        .down_count_load(down_count_load),
        .no_ram(no_ram),

        // interface to top/application

        .lpi_tick(lpi_tick),                 
        .lpi_fw(lpi_fw),  
        .scr_bypass_enable(scr_bypass_enable),                         
        .tx_lpi_mode(tx_lpi_mode),      
        .tx_lpi_state(tx_lpi_state),     
        .tx_lpi_indication(tx_lpi_indication)

);

`endif



//  Encoder + PatternGen + Scrambler 40G
//  ---------------------



//  Encoder + PatternGen
//  --------------------

encode64 U_ENCODE (

          .reset                (reset_txclk),
          .clk                  (cgmii_txclk),
          .clk_ena              (cgmii_txclk_ena_int),
          .en_gen_pat           (tx_en_gen_pat),
`ifdef MTIPPCS82_EEE_ENA 
        .t_type_li              (t_type_li),  
`endif
          .tx_d_out             (cgmii_txd),
          .tx_c_out             (cgmii_txc),
          .data_out             (enc64_dout),
          .data_type            (enc64_tout)
                                                        );
          

//  Scrambler

`ifdef MTIPPCS82_EEE_ENA
        assign scrambler_bypass_c = scrambler_bypass | scr_bypass;
`endif

p8264_scr58_ptrngen U_SCR58PTRNGEN (

        .reset                  (reset_txclk),
        .clk                    (cgmii_txclk),
        .clk_ena                (cgmii_txclk_ena_int),
        .en_gen_pat49           (en_gen_pat49),
        .sel_pat                (sel_pat),
        .seed_1                 (seed_1),
        .seed_2                 (seed_2),
`ifdef MTIPPCS82_EEE_ENA
        .scrambler_bypass       (scrambler_bypass_c),
`else
        .scrambler_bypass       (scr_bypass),
`endif
        .data_in                (enc64_dout),
        .data_in_type           (enc64_tout),
        .data_out               (scr64_dout),
        .data_out_type          (scr64_tout) );


//  Transmit MLD 40G - standalone

p8264_mld_tx U_MLD_TX(

        .reset                  (reset_txclk),
        .clk                    (cgmii_txclk),
        .sw_reset               (sw_reset),
        .type_in_0              (scr64_tout),
        .data_in_0              (scr64_dout),
        .cgmii_clk_en           (cgmii_txclk_ena_int),      // out
        .cgmii_tx_tsu           (cgmii_tx_tsu),
        .disable_mld            (disable_mld),
        .mode25                 (mode25),
        .vl_intvl               (vl_intvl),
`ifdef MTIPPCS82_EEE_ENA 
        .ram_start              (ram_start),
        .down_count_enable      (down_count_enable),
        .down_count             (down_count),   
        .down_count_load        (down_count_load),        
        .no_ram                 (no_ram),
`endif
        .vl_0_enc_in            (vl_0_enc),
        .vl_1_enc_in            (vl_1_enc),
        .vl_2_enc_in            (vl_2_enc),
        .vl_3_enc_in            (vl_3_enc),
        .gb_rd                  (mld_rd),
        .data_out_66_0          (tx_mld_d0),
        .data_out_66_1          (tx_mld_d1),
        .data_out_66_2          (tx_mld_d2),
        .data_out_66_3          (tx_mld_d3),
        .marker_start           (marker_start),
        .marker_ins_cnt         (marker_ins_cnt)
);

assign cgmii_txclk_ena = cgmii_txclk_ena_int;

endmodule